package com.yl.chainStore.control.system

import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.core.toolkit.Wrappers
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.yl.chainStore.common.Constants
import com.yl.users.common.util.permListToTreeSelect1

import com.yl.chainStore.control.BaseCtrl
import com.yl.chainStore.entity.system.CompanyDictionaryDetail
import com.yl.chainStore.entity.user.CompanyUserMedicalHistoryModelType
import com.yl.chainStore.mapper.system.CompanyDictionaryDetailMapper
import com.yl.chainStore.mapper.user.CompanyUserMedicalHistoryModelMapper
import com.yl.chainStore.mapper.user.CompanyUserMedicalHistoryModelTypeMapper
import com.yl.chainStore.services.ICompanyHtmlConfigService
import com.yl.chainStore.util.medicalHistoryTypeToTree
import com.yl.common.ErrorCode
import com.yl.common.Flag
import com.yl.common.UserType
import com.yl.common.control.ResponseBody
import com.yl.common.control.returnError
import com.yl.common.control.returnSuccess
import com.yl.common.getContext
import com.yl.users.common.util.permissionsViewListToTreeSelect
import com.yl.users.entity.*
import com.yl.users.pojo.vo.SysCompanySelectVo
import com.yl.users.services.*
import org.springframework.transaction.annotation.Transactional
import org.springframework.transaction.interceptor.TransactionAspectSupport
import org.springframework.web.bind.annotation.*
import java.util.*

/**
 * 公司菜单管理视图层
 */
@RestController
@RequestMapping("sys/company")
open class SysCompanyController(
	private val iSysCompanyService: ISysCompanyService,

	private val iCompanyUserService: ICompanyUserService,

	private val iCompanyRoleService: ICompanyRoleService,

	private val iSystemService: ISystemService,

	private val iCompanyDeptService: ICompanyDeptService,

	private val iCompanyHtmlConfigService: ICompanyHtmlConfigService,

	private val companyUserMedicalHistoryModelTypeMapper: CompanyUserMedicalHistoryModelTypeMapper,
	private val companyUserMedicalHistoryModelMapper: CompanyUserMedicalHistoryModelMapper,
	private val companyDictionaryDetailMapper:CompanyDictionaryDetailMapper,
) : BaseCtrl() {


	/**
	 * 分页查询
	 */
	@PostMapping("page")
	@Transactional
	open fun page(@RequestBody body: SysCompanySelectVo): ResponseBody {

		val page = Page<SysCompany>(body.current, body.size)
		return returnSuccess(iSystemService.getCompanyPage(page, body))
	}

	/**
	 *  单个详情
	 */
	@GetMapping("detail/{id}")
	@Transactional
	open fun detail(@PathVariable id: Long): ResponseBody {
		return returnSuccess(iSysCompanyService.getCompanyDetail(id))
	}

	/**
	 * 添加公司
	 */
	@PostMapping("add")
	@Transactional(rollbackFor = [Exception::class])
	open fun add(@RequestBody company: SysCompany): ResponseBody {
		val add = iSystemService.addCompany(company)
		if (add.code != ErrorCode.SUCCESS.code) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
		}
		return add
	}

	/**
	 * 修改公司信息
	 */
	@PostMapping("update")
	@Transactional
	open fun update(@RequestBody company: SysCompany): ResponseBody {
		return iSysCompanyService.updateCompany(company)
	}

	/**
	 * 获取所有权限 树状图
	 */
	@GetMapping("getCompanyPermTree")
	@Transactional
	open fun getCompanyPermTreeSelect(): ResponseBody{
		val companyPermissionsDtos = iSystemService.getPermList()
		return returnSuccess(permListToTreeSelect1(companyPermissionsDtos, 0L))
	}

	/**
	 * 获取所有权限 树状图
	 */
	@GetMapping("getCompanyPermIds")
	@Transactional
	open fun getCompanyPermIds(): ResponseBody{
		val companyPermissionsDtos = iSystemService.getPermList()
		val ids = mutableListOf<Long>()
		for(d in companyPermissionsDtos){
			ids.add(d.permissionsId!!)
		}
		return returnSuccess(ids)
	}



	/**
	 * 获取公司菜单权限id
	 */
	@GetMapping("getPermissionIdToCompany/{id}")
	@Transactional
	open fun getPermissionIdToCompany(@PathVariable id: Long): ResponseBody {
		return returnSuccess(iSysCompanyService.getCompanySystemPermId(id))
	}

	/**
	 * 绑定权限
	 */
	@PostMapping("bindPermissionToCompanyTree")
	@Transactional(rollbackFor = [Exception::class])
	open fun bindPermissionToCompanyTree(@RequestBody body: JSONObject): ResponseBody {
		val ids = body.getJSONArray("menuIds")
		val list: List<Long> = JSONObject.parseArray(ids.toJSONString(), Long::class.java)
		val companyId = body.getLong("id")
		iSysCompanyService.reBindPermToCompany(companyId, list)
		iCompanyUserService.cleanCacheByCompany(companyId)
		return returnSuccess()
	}


	/**
	 *  获取管理员用户
	 */
	@GetMapping("getAdminUser/{id}")
	@Transactional
	open fun getAdminUser(@PathVariable id: Long): ResponseBody {
		val adminUser = iSysCompanyService.getAdminUser(id)
		val dept = iSysCompanyService.getTopDept(id)
		if (adminUser != null) {
			if (adminUser.superUserId != null && adminUser.superUserId != 0L) {
				adminUser.superior = iCompanyUserService.getUser(adminUser.superUserId!!)
			}
			val roleAndUserCheck = iCompanyUserService.getUserSubCompanyRoleIds(adminUser.id,dept.id)
			adminUser.roleIds = roleAndUserCheck
		}

		return returnSuccess(adminUser)
	}

	/**
	 * 保存管理员用户
	 */
	@PostMapping("saveAdminUser")
	@Transactional(rollbackFor = [Exception::class])
	open fun saveAdminUser(@RequestBody user: CompanyUser): ResponseBody {
		val adminUser = iSysCompanyService.getAdminUser(user.companyId)
		if (adminUser != null) {
			user.id = adminUser.id
		}
		user.userCode = "admin"
		user.flag = Flag.NEW_ADD
		user.userType = UserType.Company
		if ( user.id == 0L) {
			val addUser = iSysCompanyService.addUser(user)
			if (addUser.code != ErrorCode.SUCCESS.code) {
				return addUser
			}
		} else {
			val updateUser = iCompanyUserService.updateById(user)
			if (updateUser.code != ErrorCode.SUCCESS.code) {
				return updateUser
			}
			iCompanyUserService.removeCacheUser(user.companyId, user.id)
		}
		val topDept = iSysCompanyService.getTopDept(user.companyId)
		iCompanyDeptService.bindUserToDept( topDept.id,user.id)
		if (user.roleIds != null && user.roleIds!!.isNotEmpty()) {
			val bindUser = iCompanyUserService.bindRoles(user.id,topDept.id, user.roleIds!!)
			if (bindUser.code != ErrorCode.SUCCESS.code) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
				return bindUser
			}
		}

		return returnSuccess()
	}

	/**
	 * 获取管理员角色
	 */
	@GetMapping("getAdminRole/{id}")
	@Transactional
	open fun getAdminRole(@PathVariable id: Long): ResponseBody {
		var adminRole = iSysCompanyService.getCompanyAdminRole(id)
		if (adminRole == null) {
			adminRole = CompanyRole(roleName = "管理员",companyId = id )
		}

		val permissionsIds = iCompanyRoleService.getRolePermIds(adminRole.id)
		val roleFieldTree = iCompanyRoleService.getRoleFieldIds(id)


		adminRole.fieldIds = roleFieldTree
		adminRole.permissionsIds = permissionsIds
		return returnSuccess(adminRole)
	}

	@GetMapping ("getCompanyPerms/{id}")
	@Transactional
	open fun getCompanyPerms(@PathVariable id:Long):ResponseBody{
		return returnSuccess(permissionsViewListToTreeSelect(iSysCompanyService.getCompanyPermViewList(id),0L))
	}

	@GetMapping ("getCompanyPermsIds/{id}")
	@Transactional
	open fun getCompanyPermsIds(@PathVariable id:Long):ResponseBody{
		val companyPermViewList = iSysCompanyService.getCompanyPermViewList(id)
		val list = mutableListOf<Long>()
		for(v in companyPermViewList){
			list.add(v.id)
		}
		return returnSuccess(list)
	}

	/**
	 * 保存管理员权限
	 */
	@PostMapping("saveAdminRole")
	@Transactional(rollbackFor = [Exception::class])
	open fun saveAdminRole(@RequestBody role: CompanyRole): ResponseBody {

		val adminRole = iSysCompanyService.getCompanyAdminRole(role.companyId)
		if (adminRole != null) {
			role.id = adminRole.id
		}
		role.roleCode = "admin"
		role.roleType = 3
		if (role.id == 0L) {
			val addRole = iSysCompanyService.addCompanyRole(role)
			if (addRole.code != ErrorCode.SUCCESS.code) {
				return addRole
			}
		} else {
			val updateRole = iCompanyRoleService.update(role)
			if (updateRole.code != ErrorCode.SUCCESS.code) {
				return updateRole
			}
		}
		if (role.permissionsIds != null && role.permissionsIds!!.isNotEmpty()) {
			val bindUser = iCompanyRoleService.reBindRolePermissions(role.id, role.permissionsIds!!)
			if (bindUser.code != ErrorCode.SUCCESS.code) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
				return bindUser
			}
		}
		if (role.fieldIds != null && role.fieldIds!!.isNotEmpty()) {
			iCompanyRoleService.reBindRoleField(role.fieldIds!!, role.id)
		}
		iCompanyUserService.cleanCacheByCompany(role.companyId)
		return returnSuccess()
	}

	/**
	 * 获取公司的字段 id
	 */
	@GetMapping("getCompanyFieldId/{id}")
	@Transactional
	open fun getCompanyFieldId(@PathVariable id:Long): ResponseBody {
		return returnSuccess(iSysCompanyService.getCompanyFieldId(id))
	}

	/**
	 * 获取所有字段权限树
	 */
	@GetMapping("getAllFieldTree")
	@Transactional
	open fun getAllFieldTree(): ResponseBody {
		return returnSuccess(iSystemService.fieldTree())
	}



	/**
	 * 绑定公司字段权限
	 */
	@PostMapping("bindField")
	@Transactional(rollbackFor = [Exception::class])
	open fun bindField(@RequestBody body: JSONObject): ResponseBody {
		val ids = body.getJSONArray("fieldIds")
		val list: List<Long> = JSONObject.parseArray(ids.toJSONString(), Long::class.java)
		val companyId = body.getLong("id") ?: return returnError(ErrorCode.PARAM_EMPTY)
		iSysCompanyService.reBindFieldToCompany(companyId, list)
		iCompanyUserService.cleanCacheByCompany(companyId)
		return returnSuccess()
	}

	@PostMapping("bindAllHtmlConfig/{id}")
	@Transactional(rollbackFor = [Exception::class])
	open fun bindAllHtmlConfig(@PathVariable id:Long):ResponseBody{
		val bindAllHtmlConfig = iCompanyHtmlConfigService.bindAllToOtherCompany(508,id)
		if(bindAllHtmlConfig.bodyIsError()){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
			return bindAllHtmlConfig
		}
		return returnSuccess()
	 }

	@PostMapping("copySickModelType/{id}")
	@Transactional(rollbackFor = [Exception::class])
	open fun copySickModelType(@PathVariable id:Long):ResponseBody{

		val medicalHistoryTypeModelList = companyUserMedicalHistoryModelTypeMapper.selectTypeModelByCompanyId(510,542)

		val medicalHistoryTypeToTree = medicalHistoryTypeToTree(medicalHistoryTypeModelList, 0L)

		addModelAndType(medicalHistoryTypeToTree,0L, getContext().companyId)
		return returnSuccess()
	}

	private fun addModelAndType(list:MutableList<CompanyUserMedicalHistoryModelType>,pId:Long,companyId:Long){
		for(type in list){
			type.id = 0
			type.companyId = companyId
			type.parentId = pId
			type.subCompanyId = getContext().subCompanyId
			companyUserMedicalHistoryModelTypeMapper.insert(type)
			if(type.modelList != null){
				for(model in type.modelList!!){
					model.typeId = type.id
					model.id = 0
					model.createTime = Date()
					model.other = model.otherJson
					companyUserMedicalHistoryModelMapper.insert(model)
				}
			}
			if(type.children != null){
				addModelAndType(type.children!!,type.id,companyId)
			}
		}
	}


	@PostMapping("copySickHistoryLabel/{id}")
	open fun copySickHistoryLabel(@PathVariable id:Long):ResponseBody{
		val selectList = companyDictionaryDetailMapper.selectList(
			Wrappers.query<CompanyDictionaryDetail?>()
				.eq("dist_id", Constants.DistId.SICK_MEDICAL_HISTORY_LABEL)
				.eq("company_id", 501)
				.orderByAsc("order_num")
		)

		for(label in selectList){
			label.id = 0
			label.companyId = id
			companyDictionaryDetailMapper.insert(label)
		}
		return returnSuccess()
	}

	@PostMapping("copySickHistoryImageType/{id}")
	open fun copySickHistoryImageType(@PathVariable id:Long):ResponseBody{
		val selectList = companyDictionaryDetailMapper.selectList(
			Wrappers.query<CompanyDictionaryDetail?>()
				.eq("dist_id", Constants.DistId.CUSTOMER_IMAGE_TYPE)
				.eq("company_id", 501)
				.orderByAsc("order_num")
		)

		for(label in selectList){
			label.id = 0
			label.companyId = id
			companyDictionaryDetailMapper.insert(label)
		}
		return returnSuccess()
	}

	@PostMapping("copyAccessFollowItem/{id}")
	open fun copyAccessFollowItem(@PathVariable id:Long):ResponseBody{
		val selectList = companyDictionaryDetailMapper.selectList(
			Wrappers.query<CompanyDictionaryDetail?>()
				.eq("dist_id", Constants.DistId.ACCESS_FOLLOW_ITEM_SELECT)
				.eq("company_id", 501)
				.orderByAsc("order_num")
		)

		for(label in selectList){
			label.id = 0
			label.companyId = id
			companyDictionaryDetailMapper.insert(label)
		}
		return returnSuccess()
	}


}
